﻿using System;
using System.Collections;
using System.Linq;
using System.Text;

using GameServer.Managers;
using GameServer.Networking.Packets;
using GameServer.Virtual_Objects.Room;
using GameServer.Virtual_Objects.User;


namespace GameServer.Networking.Handlers
{
    class HANDLE_ROOM_DATA : PacketHandler
    {
        public enum Subtype : int
        {
            Start = 1,
            ServerStart = 4,
            ServerNewRound = 5,
            ServerPrepareNewRound = 6,
            NewRound = 7,
            BackToRoom = 9,
            ReadyState = 50,
            MapChange = 51,
            ModeChange = 52,
            KillLimitDeathmatchChange = 53,
            KillLimitExplosiveChange = 55,
            PingChange = 59,
            AutostartChange = 62,
            SwitchTeam = 56,
            UserLimit = 58,
            KickUser = 61,

            MagicSubtype1 = 100,
            MagicSubtype2 = 154,

            Heal = 101,
            RepairVehicle = 102,
            Damage = 103,
            DamageVehicle = 104,
            AmmoRecharge = 105,
            Spawn = 150,
            ServerKill = 152,
            VehicleKill = 153,
            WeaponSwitch = 155,
            Flag = 156,
            Suicide = 157,
            JoinVehicle = 200,
            ChangeVehicleSeat = 201,
            LeaveVehicle = 202,
            Place = 400,
            PlaceUse = 401,
            RoomReady = 402,
            ServerRoomReady = 403,
            FallDamage = 500,
            DeathCam = 800,
            ZombieResurrection = 901
        }
        public bool haveItem(virtualUser User, string Weapon)
        {
            if (User.hasItem(Weapon) || Weapon == "DA50" || Weapon == "DL01" || Weapon == "D001" || User.PCItem && (Weapon == "D501" || Weapon == "D602" || Weapon == "DG13" || Weapon == "D801" || Weapon == "D902") || Weapon == "DF01" || User.hasRetail(Weapon) || /* Retail part */ Weapon == "DF02" || Weapon == "DB03" /*end retail part*/|| Weapon == "DN01" || Weapon == "DC02" || Weapon == "DG05" || Weapon == "DB01" || Weapon == "DJ01" || Weapon == "DA02")
                return true;
            return false;
        }

        public bool isZombieWeapon(string Weapon)
        {
            if (Weapon == "DA50" || Weapon == "DA51" || Weapon == "DA52" || Weapon == "DA53" || Weapon == "DA54" || Weapon == "DN51" || Weapon == "DN52")
                return true;
            return false;
        }
        public override void Handle(virtualUser User)
        {
            try
            {
                if (Blocks.Length >= 4 && User.Room != null)
                {
                    int sourceSeat = int.Parse(Blocks[0]);
                    int roomID = int.Parse(Blocks[1]);
                    if (sourceSeat == User.RoomSlot && roomID == User.Room.ID)
                    {
                        bool doRoomUpdate = false;
                        virtualRoom currentRoom = User.Room;
                        int subtype1 = int.Parse(Blocks[3]);
                        Subtype subtype = (Subtype)subtype1;
                        int tType = int.Parse(getBlock(3));
                        int tValue = int.Parse(getBlock(6));
                        int Value = int.Parse(getBlock(9));
                        int Place1 = int.Parse(getBlock(6));
                        int Place2 = int.Parse(getBlock(7));
                        string[] ArrSorted = new string[getAllBlocks().Length];
                        Array.Copy(getAllBlocks(), ArrSorted, getAllBlocks().Length);
                        int P0 = int.Parse(getBlock(0));
                        int P1 = int.Parse(getBlock(1));
                        string[] sendBlocks = new string[Blocks.Length - 1];
                        Array.Copy(Blocks, sendBlocks, sendBlocks.Length);
                        switch (subtype)
                        {
                            case Subtype.Start:
                                {
                                    if (currentRoom.RoomMasterSlot == User.RoomSlot)
                                    {
                                        if (currentRoom.isPremMap() == true && User.Premium < 1)
                                        {
                                            User.send(new PACKET_CHAT("SYSTEM", PACKET_CHAT.ChatType.Room_ToAll, "SYSTEM >> You cannot start premium map as free user!!", 999, "NULL"));
                                            break;
                                        }
                                        else if (currentRoom.PlayerCount <= 1 && currentRoom.Mode != 7)
                                        {
                                            User.send(new PACKET_CHAT("SYSTEM", PACKET_CHAT.ChatType.Room_ToAll, "SYSTEM >> You cant start a play alone!!", 998, "NULL"));
                                            break;
                                        }
                                        else if (currentRoom.Channel == 3 && User.Rank < 2)
                                        {
                                            currentRoom.send(new PACKET_CHAT("SYSTEM", PACKET_CHAT.ChatType.Whisper, "SYSTEM >> This channel it's not available yet.", 998, "NULL"));
                                            break;
                                        }
                                        else if (currentRoom.RoomType == 1)
                                        {
                                            if (currentRoom.getSideCount(0) != currentRoom.getSideCount(1))
                                            {
                                                currentRoom.send(new PACKET_CHAT("SYSTEM", PACKET_CHAT.ChatType.Whisper, "SYSTEM >> Teems need to be balanced.", 998, "NULL"));
                                                break;
                                            }
                                        }
                                        if (Config.Debug == 0)
                                        {
                                            if (currentRoom.Channel != 4 && currentRoom.Mode != 1) if (currentRoom.Players.Count <= 1 || currentRoom.getSideCount(0) > currentRoom.getSideCount(1) + 1 || currentRoom.getSideCount(1) > currentRoom.getSideCount(0) + 1 || currentRoom.getSideCount(0) == 0 || currentRoom.getSideCount(1) == 0) break;
                                        }
                                        if (currentRoom.Start())
                                        {
                                            subtype = Subtype.ServerStart;
                                            sendBlocks[6] = currentRoom.MapID.ToString();
                                            currentRoom.Channel = User.Channel;
                                            currentRoom.RoomStatus = 2;
                                            doRoomUpdate = true;
                                            currentRoom.GameActive = true;
                                            currentRoom.send(new PACKET_INIT_PLAYER(currentRoom));
                                        }
                                    }
                                    break;
                                }
                            case Subtype.NewRound:
                                {
                                    break;
                                }
                            case Subtype.MapChange:
                                {
                                    if (currentRoom.RoomMasterSlot == User.RoomSlot)
                                    {
                                        currentRoom.MapID = tValue;
                                        sendBlocks[7] = currentRoom.Mode.ToString();
                                    }
                                    break;
                                }
                            case Subtype.AutostartChange:
                                {
                                    if (currentRoom.RoomMasterSlot == User.RoomSlot)
                                    {
                                        //User.send(new PACKET_MESSAGEBOX("Autostart not Works!"));
                                    }
                                    break;
                                }
                            case Subtype.KillLimitDeathmatchChange:
                                {
                                    if (currentRoom.RoomMasterSlot == User.RoomSlot)
                                    {
                                        currentRoom.Rounds = int.Parse(sendBlocks[6]);
                                    }
                                    break;
                                }
                            case Subtype.KillLimitExplosiveChange:
                                {
                                    if (currentRoom.RoomMasterSlot == User.RoomSlot)
                                    {
                                        if (currentRoom.Mode == 1)
                                        {
                                            if (User.Premium > 0)
                                                currentRoom.Rounds = int.Parse(sendBlocks[6]);
                                            else
                                                currentRoom.Rounds = 0;
                                        }
                                        else
                                            currentRoom.Rounds = int.Parse(sendBlocks[6]);
                                    }
                                    break;
                                }
                            case Subtype.ModeChange:
                                {
                                    if (currentRoom.RoomMasterSlot == User.RoomSlot)
                                    {
                                        int OldMode = -1;
                                        int NewMode = -1;
                                        OldMode = currentRoom.Mode;
                                        NewMode = int.Parse(Blocks[6]);
                                        #region SendChange
                                        switch (currentRoom.Channel)
                                        {
                                            case 1:
                                                if (NewMode == 1)
                                                {
                                                    currentRoom.Mode = 1;
                                                    if (User.Premium > 0)
                                                        currentRoom.Rounds = 2;
                                                    else
                                                        currentRoom.Rounds = 0;
                                                    sendBlocks[7] = (currentRoom.MapID = 12).ToString();
                                                    sendBlocks[9] = currentRoom.Rounds.ToString();
                                                }
                                                else if (NewMode == 0)
                                                {
                                                    currentRoom.Mode = 0;
                                                    sendBlocks[7] = (currentRoom.MapID = 12).ToString();
                                                    sendBlocks[8] = (currentRoom.Rounds = 3).ToString();
                                                    sendBlocks[9] = (currentRoom.Rounds = 3).ToString();
                                                }
                                                else if (NewMode == 2)
                                                {
                                                    currentRoom.Mode = 2;
                                                    sendBlocks[7] = (currentRoom.MapID = 27).ToString();
                                                    sendBlocks[8] = (currentRoom.Rounds = 2).ToString();
                                                    sendBlocks[9] = (currentRoom.Rounds = 2).ToString();
                                                    sendBlocks[10] = "2";
                                                }
                                                break;
                                            case 2:
                                                if (NewMode == 3)
                                                {
                                                    sendBlocks[7] = (currentRoom.MapID = 40).ToString();
                                                    currentRoom.MapID = 40;
                                                    sendBlocks[10] = "3";
                                                }
                                                else if (NewMode == 2)
                                                {
                                                    sendBlocks[7] = (currentRoom.MapID = 1).ToString();
                                                    sendBlocks[8] = "2";
                                                    currentRoom.Kills = 2;
                                                    currentRoom.MapID = 1;
                                                    sendBlocks[10] = "3";
                                                }
                                                break;
                                            case 3:
                                                break;
                                            case 4:
                                                if (OldMode == 7 && NewMode == 8)
                                                {
                                                    sendBlocks[7] = currentRoom.MapID.ToString();
                                                }
                                                else if (OldMode == 8 && NewMode == 7)
                                                {
                                                    sendBlocks[7] = (currentRoom.MapID = 46).ToString();
                                                }
                                                break;
                                        }
                                        #endregion
                                    }
                                    break;
                                }
                            case Subtype.KickUser:
                                {
                                    if (currentRoom.KickAlready == true || currentRoom.Mode == 1 || currentRoom.VoteKick == 0) return;
                                    if (currentRoom.VoteKickTime > 0)
                                    {
                                        if (sendBlocks[6] == "1")
                                        {
                                            currentRoom.KickYes++; sendBlocks[6] = "1";
                                        }
                                        else if (sendBlocks[6] == "0")
                                        {
                                            currentRoom.KickNo++; sendBlocks[6] = "0";
                                        }
                                    }
                                    else
                                    {
                                        currentRoom.KickSeat = int.Parse(sendBlocks[7]);
                                        currentRoom.VoteKickTime = 30;
                                        currentRoom.KickAlready = true;
                                        Array.Resize<string>(ref currentRoom.KickString, sendBlocks.Length);
                                        Array.Copy(sendBlocks, currentRoom.KickString, sendBlocks.Length);
                                        currentRoom.KickString[5] = "4";
                                        sendBlocks[6] = "1";
                                    }

                                    break;
                                }
                            case Subtype.ServerKill:
                                {
                                    if (User.Health > 0) return;
                                    User.Health = 0;
                                    break;
                                }
                            case Subtype.PingChange:
                                {
                                    if (currentRoom.RoomMasterSlot == User.RoomSlot)
                                    {
                                        currentRoom.Ping = int.Parse(Blocks[6]);
                                    }
                                    break;
                                }
                            case Subtype.ReadyState:
                                {
                                    User.isReady = !User.isReady;
                                    sendBlocks[6] = Convert.ToByte(User.isReady).ToString();
                                    break;
                                }
                            case Subtype.BackToRoom:
                                {
                                    User.Health = 0;
                                    break;
                                }
                            case Subtype.Suicide:
                                {
                                    if (currentRoom.Mode != 2 || User.Health <= 0) return;
                                    if (User.Health > 0)
                                    {
                                        User.Health = 0;
                                        User.rDeaths += 1;
                                        User.rPoints += 2;
                                        User.isSpawned = false;
                                        if (currentRoom.getSide(User) == 0) { currentRoom.KillsDeberanLeft--; } else { currentRoom.KillsNIULeft--; }
                                    }
                                    break;
                                }
                            case Subtype.SwitchTeam:
                                {
                                    if (User.isSpectating) return;
                                    if (currentRoom.RoomType != 1)
                                    {
                                        sendBlocks[7] = currentRoom.switchSide(User).ToString();
                                        sendBlocks[8] = currentRoom.RoomMasterSlot.ToString();
                                    }
                                    break;
                                }
                            case Subtype.RoomReady:
                                {
                                    subtype = Subtype.ServerRoomReady;
                                    sendBlocks[6] = "3";
                                    sendBlocks[7] = "882";
                                    sendBlocks[8] = "0";
                                    sendBlocks[9] = "1";
                                    break;
                                }
                            case Subtype.Spawn:
                                {
                                    if (User.isSpawned) return;
                                    if (currentRoom.Mode == 0)
                                        User.send(new PACKET_CLIENT_PACKET(50));
                                    if (currentRoom.Mode == 1)
                                    {
                                        sendBlocks[10] = currentRoom.SpawnLocation.ToString();
                                        sendBlocks[11] = currentRoom.SpawnLocation.ToString();
                                        sendBlocks[12] = currentRoom.SpawnLocation.ToString();
                                        currentRoom.SpawnLocation++;
                                    }
                                    if (currentRoom.Channel == 4)
                                    {
                                        currentRoom.spawnedPlayers += 1;
                                        if (currentRoom.PlayerCount == currentRoom.spawnedPlayers)
                                        {
                                            User.Room.readyZombie = true;
                                        }
                                    }
                                    User.Rockets = User.Granade = User.killFromSpawn = 0;
                                    User.SpawnProtection = 3;
                                    User.Health = 1000;
                                    User.isSpawned = true;
                                    User.Class = getBlock(7);
                                    break;
                                }
                            case Subtype.FallDamage:
                                {
                                    int totalDamage = int.Parse(Blocks[9]);
                                    int Type = int.Parse(getBlock(6));
                                    if (Type == 1)
                                    {
                                        if (totalDamage < 0 || User.Health <= 0) return;
                                        User.Health -= totalDamage;

                                        if (User.Health <= 0)
                                        {
                                            subtype = Subtype.Suicide;
                                            sendBlocks[6] = User.RoomSlot.ToString();
                                            User.Health = 0;
                                            User.rDeaths++;
                                            User.rPoints += 2;
                                            User.isSpawned = false;
                                            if (currentRoom.getSide(User) == 0) { currentRoom.KillsDeberanLeft--; } else { currentRoom.KillsNIULeft--; }
                                        }
                                        else
                                        {
                                            sendBlocks[11] = totalDamage.ToString();
                                            sendBlocks[12] = User.Health.ToString();
                                        }
                                    }
                                    else
                                    {
                                        int dSubtype = int.Parse(getBlock(3));
                                        int vehicleID = int.Parse(getBlock(8));
                                        int vehDamage = int.Parse(getBlock(9));

                                        currentRoom.Vehicles[vehicleID].Health -= vehDamage;

                                        sendBlocks[2] = "2";
                                        sendBlocks[3] = vehicleID.ToString();
                                        sendBlocks[11] = vehDamage.ToString();
                                        sendBlocks[12] = currentRoom.Vehicles[vehicleID].Health.ToString();

                                        if (currentRoom.Vehicles[vehicleID].Health <= 0)
                                        {
                                            User.rDeaths++;
                                            User.rPoints++;
                                            User.Health = 0;
                                            currentRoom.Vehicles[vehicleID].Health = 0;
                                            User.currentVehicle = null;
                                            User.isSpawned = false;
                                            if (currentRoom.getSide(User) == 0) { currentRoom.KillsDeberanLeft--; } else { currentRoom.KillsNIULeft--; }
                                            subtype = Subtype.Suicide;
                                            sendBlocks[6] = User.RoomSlot.ToString();
                                            currentRoom.send(new PACKET_ROOM_DATA(User, int.Parse(getBlock(0)), int.Parse(getBlock(1)), int.Parse(getBlock(2)), 153, 0, 1, 0, 0, 0, 1337, 7, 35, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "FFFF"));
                                        }
                                    }
                                    break;
                                }
                            case Subtype.AmmoRecharge:
                                {
                                    break;
                                }
                            case Subtype.Place:
                                {
                                    string ItemCode = Blocks[26];
                                    if (User.hasItem(ItemCode))
                                    {
                                        if (User.Plantings < 8)
                                        {
                                            User.Plantings++;
                                            sendBlocks[8] = currentRoom.AddPlacement(User, ItemCode).ToString();
                                        }
                                    }
                                    else
                                        User.disconnect();
                                    break;
                                }
                            case Subtype.ZombieResurrection:
                                {
                                    break;
                                }
                            case Subtype.Damage:
                                {
                                    int Channel = currentRoom.Channel;
                                    string Weapon = getBlock(26).Remove(getBlock(26).Length - 4);
                                    int Damage = ItemManager.getDamage(Weapon);
                                    #region Zombie
                                    if (Channel == 4)
                                    {
                                        int ZombieID = int.Parse(getBlock(7));
                                        if (ZombieID > 3)
                                        {
                                            foreach (virtualZombie _Zombie in currentRoom.Zombies)
                                            {
                                                if (_Zombie.ID == ZombieID)
                                                {
                                                    if (_Zombie.Points != 0)
                                                    {
                                                        if (_Zombie.Health > 1)
                                                        {
                                                            _Zombie.Health = (_Zombie.Health - Damage);
                                                            if (_Zombie.Health <= 0) return;

                                                            currentRoom.send(new SP_ROOM_INFO(103,
                                                                int.Parse(getBlock(0)),
                                                                int.Parse(getBlock(1)),
                                                                int.Parse(getBlock(2)),
                                                                int.Parse(getBlock(4)),
                                                                int.Parse(getBlock(5)),
                                                                int.Parse(getBlock(6)),
                                                                int.Parse(getBlock(7)),
                                                                int.Parse(getBlock(8)),
                                                                int.Parse(getBlock(9)),
                                                                int.Parse(getBlock(10)),
                                                                int.Parse(getBlock(11)),
                                                                int.Parse(getBlock(12)),
                                                                int.Parse(getBlock(13)),
                                                                int.Parse(getBlock(14)),
                                                                int.Parse(getBlock(15)),
                                                                int.Parse(getBlock(16)),
                                                                int.Parse(getBlock(17)),
                                                                getBlock(18), // X
                                                                getBlock(19), // Z
                                                                getBlock(20), // Y
                                                                getBlock(21), // 2.0000
                                                                int.Parse(getBlock(22)),
                                                                getBlock(23), // 93.0000
                                                                getBlock(24), // 1.0000
                                                                getBlock(25), // 0
                                                                getBlock(26)));
                                                            return;
                                                        }
                                                        else
                                                        {
                                                            currentRoom.highestKills++;
                                                            currentRoom.zombieKills++;
                                                            User.rKills += 1;

                                                            currentRoom.Zombies.Remove(ZombieID);
                                                            _Zombie.Health = -1;
                                                            _Zombie.ID = -1;
                                                            currentRoom.Zombies.Remove(_Zombie);

                                                            string block21 = getBlock(21);
                                                            string WeaponCheck = getBlock(26).Remove(3, 4);
                                                            int HeadshotCalculation = int.Parse(getBlock(15));

                                                            if (HeadshotCalculation == (1237 + User.SessionID))
                                                            {
                                                                if (WeaponCheck.Contains("DA") || WeaponCheck.Contains("DN") || WeaponCheck.Contains(("DJ")))
                                                                {
                                                                    User.rPoints += _Zombie.Points;
                                                                    currentRoom.zombiePoints += _Zombie.Points;
                                                                    block21 = "2.0000";

                                                                    currentRoom.send(new SP_ROOM_INFO(152,
                                                                        int.Parse(getBlock(0)),
                                                                        int.Parse(getBlock(1)),
                                                                        int.Parse(getBlock(2)),
                                                                        int.Parse(getBlock(4)),
                                                                        int.Parse(getBlock(5)),
                                                                        int.Parse(getBlock(6)),
                                                                        int.Parse(getBlock(7)),
                                                                        int.Parse(getBlock(8)),
                                                                        int.Parse(getBlock(9)),
                                                                        int.Parse(getBlock(10)),
                                                                        int.Parse(getBlock(11)),
                                                                        int.Parse(getBlock(12)),
                                                                        int.Parse(getBlock(13)),
                                                                        int.Parse(getBlock(14)),
                                                                        int.Parse(getBlock(15)),
                                                                        int.Parse(getBlock(16)),
                                                                        int.Parse(getBlock(17)),
                                                                        getBlock(18), // X
                                                                        getBlock(19), // Z
                                                                        getBlock(20), // Y
                                                                        block21, // 99.0000
                                                                        int.Parse(getBlock(22)),
                                                                        getBlock(23), // 93.0000
                                                                        getBlock(24), // 1.0000
                                                                        getBlock(25), // 0
                                                                        getBlock(26)));
                                                                }
                                                                else
                                                                {
                                                                    User.rPoints += _Zombie.Points * 2;
                                                                    currentRoom.zombiePoints += _Zombie.Points * 2;
                                                                    block21 = "99.0000";

                                                                    currentRoom.send(new SP_ROOM_INFO(152,
                                                                        int.Parse(getBlock(0)),
                                                                        int.Parse(getBlock(1)),
                                                                        int.Parse(getBlock(2)),
                                                                        int.Parse(getBlock(4)),
                                                                        int.Parse(getBlock(5)),
                                                                        int.Parse(getBlock(6)),
                                                                        int.Parse(getBlock(7)),
                                                                        int.Parse(getBlock(8)),
                                                                        int.Parse(getBlock(9)),
                                                                        int.Parse(getBlock(10)),
                                                                        int.Parse(getBlock(11)),
                                                                        int.Parse(getBlock(12)),
                                                                        int.Parse(getBlock(13)),
                                                                        int.Parse(getBlock(14)),
                                                                        int.Parse(getBlock(15)),
                                                                        int.Parse(getBlock(16)),
                                                                        int.Parse(getBlock(17)),
                                                                        getBlock(18), // X
                                                                        getBlock(19), // Z
                                                                        getBlock(20), // Y
                                                                        block21, // 99.0000
                                                                        int.Parse(getBlock(22)),
                                                                        getBlock(23), // 93.0000
                                                                        getBlock(24), // 1.0000
                                                                        getBlock(25), // 0
                                                                        getBlock(26)));
                                                                }
                                                            }
                                                            else
                                                            {
                                                                User.rPoints += _Zombie.Points;
                                                                currentRoom.zombiePoints += _Zombie.Points;

                                                                currentRoom.send(new SP_ROOM_INFO(152,
                                                                    int.Parse(getBlock(0)),
                                                                    int.Parse(getBlock(1)),
                                                                    int.Parse(getBlock(2)),
                                                                    int.Parse(getBlock(4)),
                                                                    int.Parse(getBlock(5)),
                                                                    int.Parse(getBlock(6)),
                                                                    int.Parse(getBlock(7)),
                                                                    int.Parse(getBlock(8)),
                                                                    int.Parse(getBlock(9)),
                                                                    int.Parse(getBlock(10)),
                                                                    int.Parse(getBlock(11)),
                                                                    int.Parse(getBlock(12)),
                                                                    int.Parse(getBlock(13)),
                                                                    int.Parse(getBlock(14)),
                                                                    int.Parse(getBlock(15)),
                                                                    int.Parse(getBlock(16)),
                                                                    int.Parse(getBlock(17)),
                                                                    getBlock(18), // X
                                                                    getBlock(19), // Z
                                                                    getBlock(20), // Y
                                                                    "2.0000", // 2.0000
                                                                    int.Parse(getBlock(22)),
                                                                    getBlock(23), // 93.0000
                                                                    getBlock(24), // 1.0000
                                                                    getBlock(25), // 0
                                                                    getBlock(26)));
                                                            }
                                                            return;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            User.Health = User.Health - 100;
                                            if (User.Health > 10)
                                            {
                                                currentRoom.send(new SP_ROOM_INFO(103,
                                                    int.Parse(getBlock(0)),
                                                    int.Parse(getBlock(1)),
                                                    int.Parse(getBlock(2)),
                                                    int.Parse(getBlock(4)),
                                                    int.Parse(getBlock(5)),
                                                    int.Parse(getBlock(6)),
                                                    int.Parse(getBlock(7)),
                                                    int.Parse(getBlock(8)),
                                                    int.Parse(getBlock(9)),
                                                    int.Parse(getBlock(10)),
                                                    int.Parse(getBlock(11)),
                                                    int.Parse(getBlock(12)),
                                                    int.Parse(getBlock(13)),
                                                    int.Parse(getBlock(14)),
                                                    int.Parse(getBlock(15)),
                                                    User.Health,
                                                    User.Health + 100, //Damage
                                                    getBlock(18), // X
                                                    getBlock(19), // Z
                                                    getBlock(20), // Y
                                                    getBlock(21), // 2.0000
                                                    int.Parse(getBlock(22)),
                                                    getBlock(23), // 93.0000
                                                    getBlock(24), // 1.0000
                                                    getBlock(25), // 0
                                                    getBlock(26)));

                                                sendBlocks[7] = User.Health.ToString();
                                            }
                                            else
                                            {
                                                currentRoom.send(new SP_ROOM_INFO(152,
                                                    int.Parse(getBlock(0)),
                                                    int.Parse(getBlock(1)),
                                                    int.Parse(getBlock(2)),
                                                    int.Parse(getBlock(4)),
                                                    int.Parse(getBlock(5)),
                                                    int.Parse(getBlock(6)),
                                                    int.Parse(getBlock(7)),
                                                    int.Parse(getBlock(8)),
                                                    int.Parse(getBlock(9)),
                                                    int.Parse(getBlock(10)),
                                                    int.Parse(getBlock(11)),
                                                    int.Parse(getBlock(12)),
                                                    int.Parse(getBlock(13)),
                                                    int.Parse(getBlock(14)),
                                                    int.Parse(getBlock(15)),
                                                    int.Parse(getBlock(16)),
                                                    int.Parse(getBlock(17)),
                                                    getBlock(18), // X
                                                    getBlock(19), // Z
                                                    getBlock(20), // Y
                                                    getBlock(21), // 2.0000
                                                    int.Parse(getBlock(22)),
                                                    getBlock(23), // 93.0000
                                                    getBlock(24), // 1.0000
                                                    getBlock(25), // 0
                                                    getBlock(26)));

                                                User.rDeaths++;
                                                User.isSpawned = false;
                                            }
                                        }
                                    }
                                    else
                                    {
                                    #endregion
                                        int Slot = int.Parse(getBlock(7));
                                        if (User.currentVehicle == null)
                                            if (haveItem(User, Weapon) == false) User.disconnect();
                                        Virtual_Objects.User.virtualUser Target = currentRoom.getPlayer(Slot);
                                        int HeadshotCalculation = int.Parse(getBlock(15));
                                        if (Target != null)
                                        {
                                            if (currentRoom.getSide(User) == currentRoom.getSide(Target) && currentRoom.Mode != 1) return;
                                            if (currentRoom.EndGameFreeze) return;
                                            if ((Target.Health <= 0) || currentRoom.getSide(User) == currentRoom.getSide(Target) && currentRoom.Mode != 1 || Target.SpawnProtection > 0) return; // SpawnProtection
                                            string block21 = getBlock(21);
                                            if (HeadshotCalculation == (1237 + User.SessionID))
                                            {
                                                if (currentRoom.getSide(User) == currentRoom.getSide(Target) && currentRoom.Mode != 1) return;
                                                else
                                                {
                                                    if (Weapon.Contains("DA") || Weapon.Contains("DN") || Weapon.Contains("DJ") || Weapon.Contains("DM"))
                                                    {
                                                        block21 = "2.000";
                                                    }
                                                    else
                                                    {
                                                        if (Target.Health - Damage <= 0)
                                                        {
                                                            User.send(new PACKET_CLIENT_PACKET(1));
                                                        }
                                                        block21 = "99.0000";
                                                        Damage += 200;
                                                        User.rPoints += 3;
                                                    }
                                                }
                                            }

                                            if (Target.Health - Damage <= 0)
                                            {
                                                // Death Packet
                                                tType = (int)Subtype.ServerKill;
                                                if (currentRoom.FirstBlood == false)
                                                {
                                                    currentRoom.send(new PACKET_CLIENT_PACKET(2));
                                                    currentRoom.FirstBlood = true;
                                                }
                                                // Target
                                                Target.Health = 0;
                                                Target.rDeaths++;
                                                Target.rPoints += 2;
                                                Target.isSpawned = false;
                                                // Current User
                                                User.rKills++;
                                                User.rPoints += 5;
                                                User.killFromSpawn++;
                                                if (User.killFromSpawn >= 5)
                                                {
                                                    User.send(new PACKET_CLIENT_PACKET(51));
                                                }
                                                // currentRoom
                                                if (currentRoom.Mode == 1)
                                                {
                                                    if (User.rKills > currentRoom.highestKills)
                                                    {
                                                        currentRoom.highestKills = User.rKills;
                                                    }
                                                }
                                                else if (currentRoom.Mode == 2)
                                                {
                                                    if (currentRoom.getSide(Target) == 0)
                                                    {
                                                        currentRoom.KillsDeberanLeft--;
                                                    }
                                                    else
                                                    {
                                                        currentRoom.KillsNIULeft--;
                                                    }
                                                }
                                            }
                                            else
                                                Target.Health = Target.Health - Damage;

                                            currentRoom.send(new PACKET_ROOM_DATA(User, int.Parse(getBlock(0)),
                                                int.Parse(getBlock(1)),
                                                int.Parse(getBlock(2)),
                                                tType,
                                                int.Parse(getBlock(4)),
                                                int.Parse(getBlock(5)),
                                                int.Parse(getBlock(6)),
                                                int.Parse(getBlock(7)),
                                                int.Parse(getBlock(8)),
                                                int.Parse(getBlock(9)),
                                                int.Parse(getBlock(10)),
                                                int.Parse(getBlock(11)),
                                                int.Parse(getBlock(12)),
                                                int.Parse(getBlock(13)),
                                                int.Parse(getBlock(14)),
                                                int.Parse(getBlock(15)),
                                                Target.Health,
                                                Damage,
                                                getBlock(18), // X
                                                getBlock(19), // Z
                                                getBlock(20), // Y
                                                block21, // 2.0000
                                                int.Parse(getBlock(22)),
                                                getBlock(23), // 93.0000
                                                getBlock(24), // 1.0000
                                                getBlock(25), // 0
                                                getBlock(26) // ITEM
                                            ));
                                            return;
                                        }
                                    }
                                    break;
                                }
                            case Subtype.RepairVehicle:
                                {
                                    int vehicleID = int.Parse(getBlock(6));
                                    int Health = currentRoom.Vehicles[vehicleID].Health;
                                    int MaxHealth = currentRoom.Vehicles[vehicleID].MaxHealth;
                                    int Repair = 1000;

                                    if (Health >= MaxHealth)
                                        return;

                                    int newHP = MaxHealth += Repair;
                                    if (newHP >= MaxHealth)
                                        newHP = MaxHealth;

                                    sendBlocks[2] = "2";
                                    sendBlocks[3] = "101";
                                    sendBlocks[7] = newHP.ToString();
                                    sendBlocks[8] = MaxHealth.ToString();
                                    break;
                                }
                            case Subtype.VehicleKill:
                                {
                                    sendBlocks[7] = sendBlocks[7] + 1;
                                    sendBlocks[15] = "100";
                                    sendBlocks[16] = "0";
                                    sendBlocks[17] = "1000";
                                    break;
                                }
                            case Subtype.PlaceUse:
                                {
                                    int plantingID = int.Parse(Blocks[8]);
                                    string plantingCode = getBlock(26);

                                    if (plantingCode == "DV01")
                                        if (User.Health <= 500)
                                        User.Health += 500;
                                        else if (User.Health == 600)
                                        {
                                        User.Health += 400;
                                        }
                                        else if (User.Health == 700)
                                        {
                                        User.Health += 300;
                                        }
                                        else if (User.Health == 800)
                                        {
                                        User.Health += 200;
                                        }
                                        else if (User.Health == 900)
                                        {
                                        User.Health += 100;
                                        }
                                        else User.Health = 1000;
                                    else if (plantingCode == "DU02")
                                    {
                                        User.Health -= 50;
                                        if (User.Health <= 1)
                                            User.Health = 1;
                                    }
									
                                    //if (User.Health > 1000)
                                    //    User.Health = 1000;

                                    sendBlocks[10] = User.Health.ToString();
                                    break;
                                }
                            case Subtype.UserLimit:
                                {
                                    if (currentRoom.RoomMasterSlot == User.RoomSlot)
                                    {
                                        if (currentRoom.RoomStatus == 1)
                                        {
                                            currentRoom.UserLimit = !currentRoom.UserLimit;
                                            sendBlocks[6] = (currentRoom.UserLimit == true ? 1 : 0).ToString();
                                            doRoomUpdate = true;
                                        }
                                    }
                                    break;
                                }
                            case Subtype.WeaponSwitch:
                                {
                                    User.Weapon = int.Parse(getBlock(6));
                                    break;
                                }
                            case Subtype.Heal:
                                {
                                    /*
                                     * 0 0 2 101 0 0 0 0 0 0 0 0 0 0 // Normaly Heal
                                     * 0 0 2 101 0 0 0 0 1 0 0 0 0 0 // Remove HP
                                     * 0 0 2 101 0 0 0 1 0 0 0 0 0 0 // Medic Box Station
                                    */
                                    if (User.Weapon == 101) return; // If the weapon it's stamina
                                    int TargetSlot = int.Parse(getBlock(6)); // The target 
                                    bool ToHeal = (getBlock(8) == "1" ? false : true); // If user needed to be healed or killed
                                    bool BoxStation = (getBlock(7) == "1" ? true : false); // If it's an medic station or just normal healing
                                    if (TargetSlot >= 0 && TargetSlot <= User.Room.MaxPlayers)
                                    {
                                        virtualUser _Target = User.Room.getPlayer(TargetSlot);
                                        if (_Target != null)
                                        {
                                            if (ToHeal)
                                            {
                                                if (_Target.Health <= 0 || _Target.Health >= 1000 || (User.Room.Mode != 1 && User.Room.getSide(User) != User.Room.getSide(_Target))) return; // Check for the health and don't let user to heal the other side players

                                                if (_Target.RoomSlot != User.RoomSlot && _Target.Health <= 300) // Player assist!
                                                    User.rPoints += 5;

                                                switch (User.Weapon)
                                                {
                                                    case 99: // Adrenaline
                                                        {
                                                            if (_Target.Health < 300)
                                                                _Target.Health = 300;
                                                            else _Target.Health += 100;
                                                            break;
                                                        }
                                                    case 102: // HP Kit
                                                        {
                                                            _Target.Health += 300;
                                                            break;
                                                        }
                                                    case 94: // Medic_Kit 1
                                                        {
                                                            _Target.Health += 300;
                                                            break;
                                                        }
                                                    case 95: // Medic_Kit 2
                                                        {
                                                            _Target.Health += 400;
                                                            break;
                                                        }
                                                }

                                                if (BoxStation)
                                                    _Target.Health += 500;

                                                if (_Target.Health > 1000)
                                                    _Target.Health = 1000;
                                            }
                                            else // If needed to be killed
                                            {
                                                _Target.Health -= 100; // Remove 1HP for tick!
                                                if (_Target.Health <= 1) // Send suicide if user has no HP
                                                {
                                                    subtype = Subtype.Suicide;
                                                    _Target.isSpawned = false;
                                                }
                                            }

                                            sendBlocks[7] = _Target.Health.ToString();
                                        }
                                    }
                                    break;
                                }
                            case Subtype.JoinVehicle:
                                {
                                    int vehicleID = int.Parse(Blocks[6]);
                                    currentRoom.Vehicles[vehicleID].Join(User);
                                    sendBlocks[8] = currentRoom.Vehicles[vehicleID].Health.ToString();
                                    sendBlocks[9] = currentRoom.Vehicles[vehicleID].MaxHealth.ToString();
                                    sendBlocks[10] = currentRoom.Vehicles[vehicleID].FindSeat(User).MainCT.ToString();
                                    sendBlocks[11] = currentRoom.Vehicles[vehicleID].FindSeat(User).SubCT.ToString();
                                    sendBlocks[13] = currentRoom.Vehicles[vehicleID].GetSeat(User).ToString();
                                    User.currentVehicle = currentRoom.Vehicles[vehicleID];
                                    break;
                                }
                            case Subtype.ChangeVehicleSeat:
                                {
                                    int oldSeat = User.currentVehicle.GetSeat(User);
                                    User.currentVehicle.TakeSeat(int.Parse(Blocks[7]), User);
                                    int targetSeat = User.currentVehicle.GetSeat(User);
                                    sendBlocks[7] = targetSeat.ToString();
                                    sendBlocks[8] = oldSeat.ToString();
                                    sendBlocks[9] = User.currentVehicle.FindSeat(User).MainCT.ToString();
                                    sendBlocks[10] = User.currentVehicle.FindSeat(User).SubCT.ToString();
                                    sendBlocks[11] = "0";
                                    sendBlocks[12] = oldSeat.ToString();
                                    break;
                                }
                            case Subtype.LeaveVehicle:
                                {
                                    int vehicleID = int.Parse(Blocks[6]);
                                    if (vehicleID >= 0 && vehicleID <= currentRoom.Vehicles.Length)
                                    {
                                        currentRoom.Vehicles[vehicleID].FindSeat(User).MainCT = int.Parse(Blocks[8]);
                                        currentRoom.Vehicles[vehicleID].FindSeat(User).SubCT = int.Parse(Blocks[9]);
                                        sendBlocks[7] = currentRoom.Vehicles[vehicleID].GetSeat(User).ToString();
                                        currentRoom.Vehicles[vehicleID].Leave(User);
                                        User.currentVehicle = null;
                                    }
                                    break;
                                }
                            case Subtype.DamageVehicle:
                                {
                                    int DamageDealt = 0;
                                    int vehicleID = int.Parse(getBlock(7));
                                    string Weapon = getBlock(26).Substring(0, 4);

                                    DamageDealt = ItemManager.getDamage(Weapon);
                                    if (!Weapon.Contains("DJ"))
                                        DamageDealt = DamageDealt / 2;
                                    if (User.currentVehicle != null)
                                    {
                                        DamageDealt = 500;
                                    }
                                    string[] DamageData = new string[2];

                                    if ((currentRoom.MapID == 48 && vehicleID == 5 || currentRoom.MapID == 50 && vehicleID == 1) && isZombieWeapon(Weapon) == false) return;
                                    DamageData[0] = (currentRoom.Vehicles[vehicleID].Health - DamageDealt).ToString();
                                    DamageData[1] = currentRoom.Vehicles[vehicleID].Health.ToString();

                                    currentRoom.Vehicles[vehicleID].Health -= DamageDealt;
                                    if (currentRoom.Vehicles[vehicleID].Health <= 1)
                                    {
                                        if ((vehicleID == 1 && currentRoom.MapID == 50 || vehicleID == 5 && currentRoom.MapID == 48))
                                            currentRoom.endGame();
                                        tType = 153;
                                    }
                                    currentRoom.send(new PACKET_ROOM_DATA(User,
                                          int.Parse(getBlock(0)),
                                          int.Parse(getBlock(1)),
                                          int.Parse(getBlock(2)),
                                          tType,
                                          int.Parse(getBlock(4)),
                                          int.Parse(getBlock(5)),
                                          int.Parse(getBlock(6)),
                                          int.Parse(getBlock(7)),
                                          int.Parse(getBlock(8)),
                                          int.Parse(getBlock(9)),
                                          int.Parse(getBlock(10)),
                                          int.Parse(getBlock(11)),
                                          int.Parse(getBlock(12)),
                                          int.Parse(getBlock(13)),
                                          int.Parse(getBlock(14)),
                                          DamageData[0],
                                          DamageData[1],
                                          int.Parse(getBlock(17)),
                                          getBlock(18), // X
                                          getBlock(19), // Z
                                          getBlock(20), // Y
                                          getBlock(21), // 2.0000
                                          int.Parse(getBlock(22)),
                                          getBlock(23), // 93.0000
                                          getBlock(24), // 1.0000
                                          getBlock(25), // 0
                                          Weapon));
                                    return;
                                }
                            case Subtype.Flag:
                                {
                                    if (currentRoom.Channel == 1) return;
                                    int flagNumber = int.Parse(getBlock(6));
                                    int Side = currentRoom.getSide(User);
                                    int oldState = (int)currentRoom.Flags[flagNumber];
                                    if (oldState == -1)
                                    {
                                        currentRoom.Flags[flagNumber] = Side;
                                        User.rFlags++;
                                        User.rPoints += 3;
                                    }
                                    else
                                    {
                                        currentRoom.Flags[flagNumber] = -1;
                                    }

                                    currentRoom.send(new PACKET_ROOM_DATA(User, 156,
                                         int.Parse(getBlock(0)),
                                         int.Parse(getBlock(1)),
                                         int.Parse(getBlock(2)),
                                         0,
                                         0,
                                         flagNumber,
                                         (int)currentRoom.Flags[flagNumber],
                                         oldState,
                                         0,
                                         0,
                                         0,
                                         0
                                         ));
                                    break;
                                }
                            default:
                                {
                                    Log.WriteLine("New Subtype for RoomData: " + subtype);
                                    Log.WriteLine("Blocks: " + string.Join(" ", getAllBlocks()));
                                    Log.WriteLine("This subtype has been blocked and rejected");
                                    return;
                                }
                        }

                        sendBlocks[3] = ((int)subtype).ToString();

                        if (subtype == Subtype.ServerRoomReady)
                        {
                            User.send(new PACKET_PLAYER_NUMBER(currentRoom));
                            User.send(new PACKET_INIT_PLAYER(currentRoom));
                            User.send(new PACKET_ROOM_DATA(User, sendBlocks));
                        }
                        else if (subtype == Subtype.KickUser)
                        {
                            foreach (virtualUser Players in currentRoom.getTeamPlayer(currentRoom.getSide(User)))
                            {
                                Players.send(new PACKET_ROOM_DATA(User, sendBlocks));
                            }
                        }
                        else
                        {
                            currentRoom.send(new PACKET_ROOM_DATA(User, sendBlocks));
                        }

                        //subtype1 = Convert.ToInt32(subtype);

                        //sendBlocks[3] = subtype1.ToString();

                        //if (subtype == Subtype.ServerRoomReady)
                        //{
                        //    User.send(new PACKET_ROOM_DATA(User, sendBlocks));
                        //    User.send(new PACKET_PLAYER_NUMBER(currentRoom));
                        //}
                        //else if (subtype == Subtype.KickUser)
                        //{
                        //    foreach (virtualUser Players in currentRoom.getTeamPlayer(currentRoom.getSide(User)))
                        //    {
                        //        Players.send(new PACKET_ROOM_DATA(User, sendBlocks));
                        //    }
                        //}
                        //else if (subtype == Subtype.BackToRoom || subtype == Subtype.DeathCam || subtype == Subtype.MagicSubtype1 || subtype == Subtype.MagicSubtype2)
                        //{
                        //    User.send(new PACKET_ROOM_DATA(User, sendBlocks));
                        //}
                        //else
                        //{
                        //    currentRoom.send(new PACKET_ROOM_DATA(User, sendBlocks));
                        //}

                        foreach (Virtual_Objects.User.virtualUser _User in UserManager.getUsersInChannel(currentRoom.Channel, false))
                        {
                            _User.send(new PACKET_ROOM_LIST(_User, _User.Page));
                            //_User.send(new PACKET_ROOM_UPDATE(currentRoom));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                //Log.WriteError(ex.Message + " at handle room data");
            }
        }
    }
}